package inv.cal.logic;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TreeMap;

public class Manager {
	private Calendar cal;
	private Locale locale;
	private Date selectedDate;
	private Date returnDate;
	private SimpleDateFormat sdf;
	
	public final Comparator<Date> dateComparator = new Comparator<Date>(){
		public int compare(Date o1, Date o2) {
			return sdf.format(o1).compareTo(sdf.format(o2));
		}
	};
	
	private List<Integer> years	= null;
	
	TreeMap<Date, List<EventsInfo>> dayInfo	= new TreeMap<Date, List<EventsInfo>>(dateComparator);
	
	public Manager(Calendar cal, Locale locale) {
		this.cal	= cal;
		this.locale	= locale;
		this.sdf	= new SimpleDateFormat("yyyyMMdd", locale);
	}
	
	public Integer getNumberOfDaysInWeek() {
		int numberOfDaysInWeek = cal.getActualMaximum(Calendar.DAY_OF_WEEK);
		return numberOfDaysInWeek;
	}
	
	public Integer getNumberOfDaysInMonth(){
		int numberOfDaysInMonth	= cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		return numberOfDaysInMonth;
	}
	
	public Integer getNumberOfWeeksInMonth(){
		int numberOfWeeksInMonth	= cal.getActualMaximum(Calendar.WEEK_OF_MONTH);
		return numberOfWeeksInMonth;
	}
	
	public Day getDay(int dayInWeek, int week){
		Calendar cal2 = (Calendar)cal.clone();
		cal2.set(Calendar.DAY_OF_WEEK, dayInWeek);
		cal2.set(Calendar.WEEK_OF_MONTH, week);
		
		Day day	= new Day();
		day.setDate(cal2.getTime());
		
		if(cal2.get(Calendar.MONTH) != cal.get(Calendar.MONTH))
			return null;
		
		return day;
	}
	
	public Week getWeek(int weekInMonth){
		Calendar cal2 = (Calendar)cal.clone();
		cal2.set(Calendar.WEEK_OF_MONTH, weekInMonth+1);
		
		Week week	= new Week();
		week.setWeek(cal2.get(Calendar.WEEK_OF_YEAR));
		
		return week;
	}
	
	public String getDayName(int dayInWeek){
		String name	= "";
		if(dayInWeek > 0){
			Calendar cal2	= (Calendar)cal.clone();
			cal2.set(Calendar.DAY_OF_WEEK, dayInWeek);
			name = cal2.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, locale);
		}
		
		return name;
	}
	
	public boolean isHoliday(Date date){
		Calendar cal2	= (Calendar)cal.clone();
		cal2.setTime(date);
		
		if(cal2.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal2.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
			return true;
		
		return false;
	}
	
	public List<String> getMonths(){
		Calendar cal2	= (Calendar)cal.clone();
		int firstMonth	= cal2.getMinimum(Calendar.MONTH);
		int lastMonth 	= cal2.getMaximum(Calendar.MONTH);
		
		List<String> array	= new ArrayList<String>(12);
		for(int i=firstMonth;i<=lastMonth;i++){
			cal2.set(Calendar.MONTH, i);
			array.add(cal2.getDisplayName(Calendar.MONTH, Calendar.LONG, locale));
		}
		
		return array;
	}
	
	public List<Integer> getYears(){
		if(years == null){
			List<Integer> years	= new ArrayList<Integer>();
			int startingYear = cal.get(Calendar.YEAR);
			for(int year=startingYear; year<startingYear+2; startingYear++){
				years.add(year);
			}
		}
		
		return years;
	}
	
	public void addAll(List<EventsInfo> events){
		if(events != null)
			for(EventsInfo day: events){
				List<EventsInfo> eventList	= dayInfo.get(day.getDate());
				if(eventList == null)
					eventList	= new ArrayList<EventsInfo>();
				eventList.add(day);
				this.dayInfo.put(day.getDate(), eventList);
			}
	}
	
	public void clearEvents(){
		this.dayInfo.clear();
	}
	
	public List<EventsInfo> getDays(Date date){
		return dayInfo.get(date);
	}
	
	public void setYear(int year){
		cal.set(Calendar.YEAR, year);
	}
	
	public void setMonth(int month){
		cal.set(Calendar.MONTH, month);
	}
	
	public Integer getSelectedYear(){
		return cal.get(Calendar.YEAR);
	}
	
	public int getSelectedMonthIndex(){
		return cal.get(Calendar.MONTH);
	}

	public void setYears(List<Integer> years) {
		this.years = years;
	}
	
	public void calculateYearsByEvents(){
		java.util.Calendar cal1 = (java.util.Calendar)cal.clone();
		cal1.setTime(new Date());
		int year = cal1.get(Calendar.YEAR);
		int startingYear = year;
		int endYear = year+1;
		
		if(dayInfo != null)
			for(Date date: dayInfo.keySet()){
				cal1.setTime(date);
				year = cal1.get(Calendar.YEAR);

				if(startingYear > year)
					startingYear = year;
				else
					if(endYear < year)
						endYear = year;
			}
		
		years	= new ArrayList<Integer>();
		for(int i=startingYear; i<=endYear; i++)
			years.add(i);
	}
	
	
	public int getFromDate(Date date, int field){
		Calendar cal1	 = (Calendar)cal.clone();
		cal1.setTime(date);
		
		return cal1.get(field);
	}

	public void setSelectedDate(Date selectedDate) {
		this.selectedDate = selectedDate;
	}

	public Date getSelectedDate() {
		return selectedDate;
	}

	public Date getReturnDate() {
		return returnDate;
	}

	public void setReturnDate(Date returnDate) {
		this.returnDate = returnDate;
	}
}
